const fs = require("fs");
const express = require("express");
// multer
const multer = require("multer");

const { expressjwt } = require("express-jwt");
const jwt = require("jsonwebtoken");

const md5 = require("md5");
const dayjs = require("dayjs");

const app = express();
// multer 上传的文件存放的目录 "./public/uploads"
const upload = multer({ dest: "./public/uploads" });

// 解码json
app.use(express.json());
// 解码fromData multer
app.use(upload.single("thingfile"));

app.post("/upload", (req, res) => {
  res.send(req.body);
});

app.get("/xml", (req, res) => {
  const html = String.raw;
  res.type("xml");
  res.send(html`
    <user>
      <name>jack</name>
      <age>20</age>
      <gender>boy</gender>
    </user>
  `);
});

app.get("/mp4", (req, res) => {
  res.sendFile("f:/video/ajax9.mp4");
});

app.get("/img", (req, res) => {
  res.sendFile("F:/code-211/mock-data/public/cat.jpg");
});

// 拦截查身份
// app.use(
//   expressjwt({
//     secret: "abc123",
//     algorithms: ["HS256"],
//     getToken(req) {
//       if (req.headers.token) {
//         return req.headers.token;
//       }
//       return null;
//     },
//   }).unless({
//     path: ["/login", '/lists', "/posts", "/comments","/navs", { url: /^\/posts\/\d$/ }, { url: /^\/lists\/\d+$/ }, { url: /^\/navs\/\d+$/ }],
//   })
// );

// 错误拦截，自定义错误信息
app.use((err, req, res, next) => {
  if (err.name === "UnauthorizedError") {
    if (err.inner.name === "TokenExpiredError") {
      res.status(401);
      res.send({ msg: "token 过期" });
      return;
    }
    res.status(401);
    res.send({ msg: "token 验证失败" });
    return;
  } else {
    next();
  }
});

app.post("/login", (req, res) => {
  if (req.body.name && req.body.password === false) {
    res.status(400);
    res.send({ msg: "用户名或密码错误" });
    return;
  }
  const db = JSON.parse(fs.readFileSync("./db.json").toString());
  const r = db.users.find(
    (el) => el.name === req.body.name && el.password === md5(req.body.password)
  );
  // jwt.sign(加密的内容,秘钥，)
  if (r) {
    const token = jwt.sign(
      {
        name: r.name,
        email: r.email,
        // 过期时间
        exp: Math.floor(Date.now() / 1000) + 3600,
      },
      "abc123"
    );
    res.send(token);
  } else {
    res.status(401);
    res.send({ msg: "用户名或密码错误" });
  }
});

// http://127.0.0.1:3000/users
// 拦截添加
app.post("/users", (req, res, next) => {
  if (!!req.body.name === false) {
    res.status(400);
    res.send({ msg: "用户名必须填写" }); //拦截
    return;
  }
  if (/^[a-z]{2,18}$/.test(req.body.name) === false) {
    res.status(400);
    res.send({ msg: "用户名必须2-18位" }); //拦截
    return;
  }
  if (!!req.body.email === false) {
    res.status(400);
    res.send({ msg: "邮箱必须填写" }); //拦截
    return;
  }
  if (
    /^(([^<>()[\]\\.,;:\s@"]+(\.[^<>()[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/.test(
      req.body.email
    ) === false
  ) {
    res.status(400);
    res.send({ msg: "邮箱格式错误" }); //拦截
    return;
  }
  if (!!req.body.password === false) {
    res.status(400);
    res.send({ msg: "密码名必须填写" }); //拦截
    return;
  }
  if (/^.{6,18}$/.test(req.body.password) === false) {
    res.status(400);
    res.send({ msg: "密码必须6-18" }); //拦截
    return;
  }
  if (req.body.age > 100 || req.body.age < 18) {
    res.status(400);
    res.send({ msg: "年龄必须18-100" }); //拦截
    return;
  }

  const db = JSON.parse(fs.readFileSync("./db.json").toString());

  // 用户名唯一验证
  if (db.users.find((el) => el.name === req.body.name) !== undefined) {
    res.status(400);
    res.send({ msg: "用户名已存在" }); //拦截
    return;
  }
  // 邮箱唯一验证
  if (db.users.find((el) => el.email === req.body.email) !== undefined) {
    res.status(400);
    res.send({ msg: "邮箱已存在" }); //拦截
    return;
  }

  // 改写输入参数passoword
  req.body.password = md5(req.body.password);
  // 新增额外数据
  req.body.ctime = dayjs(new Date()).format("YYYY-MM-DD HH:mm:ss"); //添加时间
  req.body.mtime = dayjs(new Date()).format("YYYY-MM-DD HH:mm:ss"); // 修改时间

  next(); // 放行
});

app.put("/users/:id", (req, res, next) => {
  if (!!req.body.name === false) {
    res.status(400);
    res.send({ msg: "用户名必须填写" }); //拦截
    return;
  }
  if (/^[a-z]{2,18}$/.test(req.body.name) === false) {
    res.status(400);
    res.send({ msg: "用户名必须2-18位" }); //拦截
    return;
  }
  if (!!req.body.email === false) {
    res.status(400);
    res.send({ msg: "邮箱必须填写" }); //拦截
    return;
  }
  if (
    /^(([^<>()[\]\\.,;:\s@"]+(\.[^<>()[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/.test(
      req.body.email
    ) === false
  ) {
    res.status(400);
    res.send({ msg: "邮箱格式错误" }); //拦截
    return;
  }
  if (req.body.age > 100 || req.body.age < 18) {
    res.status(400);
    res.send({ msg: "年龄必须18-100" }); //拦截
    return;
  }

  const db = JSON.parse(fs.readFileSync("./db.json").toString());

  // 获取原来的值
  const oldUser = db.users.find((el) => el.id === +req.params.id);
  // 用户名唯一验证
  const user = db.users.find((el) => el.name === req.body.name);
  if (oldUser.name !== req.body.name && user !== undefined) {
    res.status(400);
    res.send({ msg: "用户名已存在" }); //拦截
    return;
  }
  // 邮箱唯一验证
  const userByEmail = db.users.find((el) => el.email === req.body.email);
  if (oldUser.email !== req.body.email && userByEmail !== undefined) {
    res.status(400);
    res.send({ msg: "邮箱已存在" }); //拦截
    return;
  }

  // 新增额外数据
  req.body.mtime = dayjs(new Date()).format("YYYY-MM-DD HH:mm:ss");

  next(); // 放行
});

app.patch("/users/:id", (req, res, next) => {
  const db = JSON.parse(fs.readFileSync("./db.json").toString());
  // 获取原来的值
  const oldUser = db.users.find((el) => el.id === +req.params.id);

  if (!!req.body.name === true) {
    if (!!req.body.name === false) {
      res.status(400);
      res.send({ msg: "用户名必须填写" }); //拦截
      return;
    }
    if (/^[a-z]{2,18}$/.test(req.body.name) === false) {
      res.status(400);
      res.send({ msg: "用户名必须2-18位" }); //拦截
      return;
    }

    // 用户名唯一验证
    const user = db.users.find((el) => el.name === req.body.name);
    if (oldUser.name !== req.body.name && user !== undefined) {
      res.status(400);
      res.send({ msg: "用户名已存在" }); //拦截
      return;
    }
  }

  if (!!req.body.email === true) {
    if (!!req.body.email === false) {
      res.status(400);
      res.send({ msg: "邮箱必须填写" }); //拦截
      return;
    }
    if (
      /^(([^<>()[\]\\.,;:\s@"]+(\.[^<>()[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/.test(
        req.body.email
      ) === false
    ) {
      res.status(400);
      res.send({ msg: "邮箱格式错误" }); //拦截
      return;
    }

    // 邮箱唯一验证
    const userByEmail = db.users.find((el) => el.email === req.body.email);
    if (oldUser.email !== req.body.email && userByEmail !== undefined) {
      res.status(400);
      res.send({ msg: "邮箱已存在" }); //拦截
      return;
    }
  }

  if (!!req.body.age === true) {
    if (req.body.age > 100 || req.body.age < 18) {
      res.status(400);
      res.send({ msg: "年龄必须18-100" }); //拦截
      return;
    }
  }

  // 新增额外数据
  req.body.mtime = dayjs(new Date()).format("YYYY-MM-DD HH:mm:ss");

  next(); // 放行
});

module.exports = app;
